package br.com.velp.sudecap.mb.decreto;

import br.com.velp.sudecap.comum.BaseController;
import br.com.velp.sudecap.comum.InterfaceCadastro;
import br.com.velp.sudecap.comum.ValidationException;
import br.com.velp.sudecap.entidade.Decreto;
import br.com.velp.sudecap.entidade.Reratificacao;
import br.com.velp.sudecap.enumerator.PaginaEnum;
import br.com.velp.sudecap.enumerator.StatusDecretoEnum;
import br.com.velp.sudecap.enumerator.TipoDecretoEnum;
import br.com.velp.sudecap.service.DecretoService;
import br.com.velp.sudecap.web.util.MensagemUtil;
import java.util.*;
import javax.faces.model.SelectItem;
import org.apache.commons.lang.StringUtils;
import org.lindbergframework.spring.scope.AccessScoped;
import org.primefaces.event.DateSelectEvent;
import org.primefaces.event.SelectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * <sumario> <objetivo> "Rastreabilidade" </objetivo> <autor> EDUARDO SANTOS DE
 * OLIVEIRA </autor> <versao>1.0.0.0</versao> <data_criacao> 17.10.2012
 * </data_criacao> <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisito_afetado> RF006.02 - Cadastrar Decreto </requisito_afetado>
 * <descricao> Managead Bean responsável por controlar as operações de
 * Inclusão/Alteração/Detalhamento de Decretos </descricao> </sumario>
 */
@Controller("manterDecreto")
@AccessScoped
public class ManterDecreto extends BaseController implements InterfaceCadastro {

    public static final Long serialVersionUID = 1L;
    private Decreto decreto;
    private Reratificacao reratificacaoRemovida;
    private List<SelectItem> listaTipos;
    private List<SelectItem> listaStatus;
    private List<SelectItem> listaDecretos;
    private List<Reratificacao> reratificacoes;
    private Long idDecretoSelecionado;
    private boolean isDetalhamento;
    private boolean reRatificar;
    private boolean revogar;
    @Autowired
    private DecretoService decretoService;

    @Override
    public String setup() {

	this.decreto = new Decreto();
	this.reratificacoes = new ArrayList<Reratificacao>();
	this.listaTipos = obterSelectItemPopulado(true, TipoDecretoEnum.values());
	this.listaStatus = obterSelectItemPopulado(true, StatusDecretoEnum.values());
	this.listaDecretos = obterSelectItemInicializado();
	this.isDetalhamento = false;
	this.reRatificar = false;
	this.revogar = false;

	return PaginaEnum.MANTER_DECRETO.getValue();

    }

    @Override
    public String editSetup() {

	String pagina = setup();

	this.decreto = this.decretoService.obterPorId(this.idDecretoSelecionado);
	this.reRatificar = !this.decreto.getReratificacoes().isEmpty();
	this.revogar = (this.decreto.getDecretoRevogado() != null);
	this.reratificacoes.addAll(this.decreto.getReratificacoes());
	this.listaDecretos = obterSelectItemInicializado();

	return pagina;

    }

    @Override
    public String detalhar() {

	String pagina = editSetup();
	this.isDetalhamento = true;

	return pagina;

    }

    @Override
    public String salvar() throws Exception {

	try {

	    if (this.decreto.getDataCaducacao() == null) {
		MensagemUtil.exibirMensagemErro("global", MensagemUtil.getMensagem("decretoDataVencimentoCampoObrigatorio"));
		return null;
	    }
	    
	    if(this.reRatificar && this.reratificacoes.isEmpty()){
		MensagemUtil.exibirMensagemErro("global", MensagemUtil.getMensagem("decretoNenhumaReratificacaoAdicionada"));
		return null;
	    }
	    
	    if(this.revogar && this.decreto.getDecretoRevogado() == null){
		MensagemUtil.exibirMensagemErro("global", MensagemUtil.getMensagem("decretoNenhumDecretoRevogado"));
		return null;
	    }

	    this.reRatificar = !this.reratificacoes.isEmpty();
	    this.revogar = this.decreto.getDecretoRevogado() != null;

	    this.decreto.getReratificacoes().clear();
	    this.decreto.getReratificacoes().addAll(this.reratificacoes);

	    if (this.decreto.getId() == null) {
		this.decreto.setIdUsuarioCadastro(getContexto().getUsuario().getId());
		this.decretoService.salvar(this.decreto);
		this.listaDecretos = obterSelectItemInicializado();
	    } else {
		this.decreto.setDataAlteracao(new Date());
		this.decreto.setIdUsuarioAlteracao(getContexto().getUsuario().getId());
		this.decretoService.atualizar(this.decreto);
	    }

	    this.isDetalhamento = true;
	    MensagemUtil.exibirMensagemInformacao("global", MensagemUtil.getMensagem("registro_salvo_sucesso"));

	} catch (ValidationException e) {
	    for (String key : e.getMensagens()) {
		MensagemUtil.exibirMensagemErro("global", MensagemUtil.getMensagem(key));
	    }
	} catch (Exception e) {
	    MensagemUtil.exibirMensagemErro("global", e.getMessage());
	}

	return null;

    }

    @Override
    public String voltar() {

	return PaginaEnum.CONSULTAR_DECRETO.getValue();

    }

    /**
     *
     * Responsável Por Calcular a Data de Vencimento do Decreto, de Acordo Com o
     * Tipo de Decreto Selecionado
     *
     * 1. Interesse Social - Vencimento de Dois Anos 2. Utilidade Pública -
     * Vencimento de Cinco Anos
     *
     */
    public void calcularDataVencimentoDecreto() {

	if (this.decreto.getDataPublicacao() != null) {
	    Calendar calendar = GregorianCalendar.getInstance();
	    calendar.setTime(this.decreto.getDataPublicacao());
	    if (TipoDecretoEnum.INTERESSE_SOCIAL.getValue().equals(this.decreto.getTipoDecreto())) {
		calendar.roll(Calendar.YEAR, 2);
		this.decreto.setDataCaducacao(calendar.getTime());
	    } else if (TipoDecretoEnum.UTILIDADE_PUBLICA.getValue().equals(this.decreto.getTipoDecreto())) {
		calendar.roll(Calendar.YEAR, 5);
		this.decreto.setDataCaducacao(calendar.getTime());
	    } else {
		this.decreto.setDataCaducacao(null);
	    }
	} else {
	    this.decreto.setDataCaducacao(null);
	}

    }

    public void selecionarDecreto(SelectEvent event) {

	Decreto decretoSelecionado = (Decreto) event.getObject();

	if (this.decreto.equals(decretoSelecionado)) {
	    MensagemUtil.exibirMensagemAlerta("global", MensagemUtil.getMensagem("decretoNaoEhPossivelVincularAoMesmoDecreto"));
	    return;
	}

	if (!contemDecreto(decretoSelecionado)) {
	    Reratificacao reratificacao = new Reratificacao();
	    reratificacao.setDecretoOriginal(this.decreto);
	    reratificacao.setDecretoReratificado(decretoSelecionado);
	    this.reratificacoes.add(reratificacao);
	} else {
	    MensagemUtil.exibirMensagemAlerta("global", MensagemUtil.getMensagem("decretoJaAdicionado"));
	}

    }

    public void removerReratificacao() {
	if (this.reratificacaoRemovida != null) {
	    this.reratificacoes.remove(this.reratificacaoRemovida);
	    this.decreto.getReratificacoes().remove(this.reratificacaoRemovida);
	    this.reratificacaoRemovida = null;
	}
    }

    private boolean contemDecreto(Decreto decreto) {
	for (Reratificacao reratificacao : this.reratificacoes) {
	    if (reratificacao.getDecretoReratificado().equals(decreto)) {
		return true;
	    }
	}
	return false;
    }

    public void complementarURL() {
	if (StringUtils.isNotBlank(this.decreto.getEnderecoDom())
		&& !this.decreto.getEnderecoDom().startsWith(MensagemUtil.getMensagem("urlPadrao"))
		&& !this.decreto.getEnderecoDom().startsWith(MensagemUtil.getMensagem("urlPadraoSec"))) {
	    this.decreto.setEnderecoDom((MensagemUtil.getMensagem("urlPadrao") + this.decreto.getEnderecoDom()).toLowerCase());
	}
    }

    public void handleDateSelect(DateSelectEvent event) {
	this.decreto.setDataPublicacao(event.getDate());
	calcularDataVencimentoDecreto();
    }

    public List<Decreto> filtrarDecretos(String valor) {
	return this.decretoService.recuperarDecretos(this.getDecreto().getId(), valor);
    }

    public void limparCampoRevogado() {
	this.revogar = !this.revogar;
	if (!this.revogar) {
	    this.decreto.setDecretoRevogado(null);
	}
    }

    public void limparDecretosReratificados() {
	this.reRatificar = !this.reRatificar;
	if (!this.reRatificar && !this.reratificacoes.isEmpty()) {
	    exibirPainelDialog("pnLimparReratificacoes");
	}
    }
    
    public void limparDecretoRevogado(){
	this.revogar = !this.revogar;
	if(!this.revogar && this.decreto.getDecretoRevogado() != null){
	    exibirPainelDialog("pnLimparDecretoRevogado");
	}
    }
    
    public void limparReratificados(){
	this.reratificacoes.clear();
    }
    
    public void limparRevogado(){
	this.decreto.setDecretoRevogado(null);
    }
    
    public void configurarReratificar(){
	this.reRatificar = true;
    }
    
    public void configurarRevogar(){
	this.revogar = true;
    }

    public void aoSelecionarRevogado(SelectEvent event) {
	Decreto decretoRevogado = (Decreto) event.getObject();
	this.decreto.setDecretoRevogado(decretoRevogado);
    }

    public void blurDecretoRevogado() {
	this.revogar = (this.decreto.getDecretoRevogado() != null);
    }

    public boolean getExibirConfirmacao() {
	return !this.reRatificar;
    }

    // <editor-fold desc="GETTERS AND SETTERS" defaultstate="collapsed">            
    public StatusDecretoEnum getStatusDecreto() {
	return this.decretoService.recuperarStatusDecreto(this.decreto);
    }

    public Decreto getDecreto() {
	return decreto;
    }

    public void setDecreto(Decreto decreto) {
	this.decreto = decreto;
    }

    public Long getIdDecretoSelecionado() {
	return idDecretoSelecionado;
    }

    public void setIdDecretoSelecionado(Long idDecretoSelecionado) {
	this.idDecretoSelecionado = idDecretoSelecionado;
    }

    public boolean isIsDetalhamento() {
	return isDetalhamento;
    }

    public void setIsDetalhamento(boolean isDetalhamento) {
	this.isDetalhamento = isDetalhamento;
    }

    public boolean isReRatificar() {
	return reRatificar;
    }

    public void setReRatificar(boolean reRatificar) {
	this.reRatificar = reRatificar;
    }

    public boolean isRevogar() {
	return revogar;
    }

    public void setRevogar(boolean revogar) {
	this.revogar = revogar;
    }

    public List<SelectItem> getListaTipos() {
	return listaTipos;
    }

    public void setListaTipos(List<SelectItem> listaTipos) {
	this.listaTipos = listaTipos;
    }

    public List<SelectItem> getListaStatus() {
	return listaStatus;
    }

    public void setListaStatus(List<SelectItem> listaStatus) {
	this.listaStatus = listaStatus;
    }

    public List<SelectItem> getListaDecretos() {
	return listaDecretos;
    }

    public void setListaDecretos(List<SelectItem> listaDecretos) {
	this.listaDecretos = listaDecretos;
    }

    public List<Reratificacao> getReratificacoes() {
	return reratificacoes;
    }

    public void setReratificacoes(List<Reratificacao> reratificacoes) {
	this.reratificacoes = reratificacoes;
    }

    public Reratificacao getReratificacaoRemovida() {
	return reratificacaoRemovida;
    }

    public void setReratificacaoRemovida(Reratificacao reratificacaoRemovida) {
	this.reratificacaoRemovida = reratificacaoRemovida;
    }
    // </editor-fold>  
}
